#include "lcd_init.h"
#include "stdio.h"
#include <string.h>
// #include "app.h"
#define Command 0
#define Parameter 1
typedef void (*FunType)(void);

// 时序参数结构体
typedef struct
{
    uint16_t width;      // 屏幕宽度 (H)
    uint16_t height;     // 屏幕高度 (V)
    uint16_t hbp;        // 水平后廊 (HBP)
    uint16_t hpw;        // 水平同步脉冲宽度 (HS)
    uint16_t hfp;        // 水平前廊 (HFP)
    uint16_t vbp;        // 垂直后廊 (VBP)
    uint16_t vpw;        // 垂直同步脉冲宽度 (VS)
    uint16_t vfp;        // 垂直前廊 (VFP)
    uint16_t frame_rate; // 刷新率 (Hz)
    uint32_t pll_freq;   // PLL频率 (MHz)
} LCD_Timing_t;

// 正确计算串行RGB模式的像素时钟频率
uint32_t LCD_CalculateSerialPixelClock(LCD_Timing_t *timing)
{
    // 串行RGB模式：每个像素需要3个时钟周期传输(R/G/B各8位)
    uint32_t h_total = timing->width * 3 + timing->hbp + timing->hpw + timing->hfp;
    uint32_t v_total = timing->height + timing->vbp + timing->vpw + timing->vfp;
    uint32_t total_pixels_per_frame = h_total * v_total;
    uint32_t pixel_clock = total_pixels_per_frame * timing->frame_rate;

    return pixel_clock;
}

// 计算像素时钟分频值
uint32_t LCD_CalculateLCDC_FPR(uint32_t pll_freq, uint32_t pclk_freq, uint8_t is_serial_mode)
{
    // 串行模式: PCLK = PLL_freq * (LCDC_FPR + 1) / 2^20 * 4
    uint64_t lcdc_fpr;

    if (is_serial_mode)
    {
        // PCLK = PLL_freq * (LCDC_FPR + 1) / 2^20 * 4
        lcdc_fpr = ((uint64_t)pclk_freq * (1 << 20)) / (pll_freq * 4) - 1;
    }
    else
    {
        // 并行模式: PCLK = PLL_freq * (LCDC_FPR + 1) / 2^20
        lcdc_fpr = ((uint64_t)pclk_freq * (1 << 20)) / pll_freq - 1;
    }

    return (uint32_t)lcdc_fpr;
}

//**********************************write function begin********************************************
void wr_cmd_4spi_8bcs(uint8_t par)
{
    SPI_CSXLow();
    SPI_DCXLow();
    for (uint8_t i = 0; i < 8; i++)
    {
        SPI_SCLLow();
        if (par & 0x80)
        {
            SPI_SDAHigh();
        }
        else
        {
            SPI_SDALow();
        }
        SPI_SCLHigh();
        par <<= 1;
    }
    SPI_CSXHigh();
}
void wr_dat_4spi_8bcs(uint8_t par)
{
    SPI_CSXLow();
    SPI_DCXHigh();
    for (uint8_t i = 0; i < 8; i++)
    {
        SPI_SCLLow();
        if (par & 0x80)
        {
            SPI_SDAHigh();
        }
        else
        {
            SPI_SDALow();
        }
        SPI_SCLHigh();
        par <<= 1;
    }
    SPI_CSXHigh();
}

void sda_state(uint8_t state)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    if (state == 0)
    {
        GPIO_InitStruct.Pin = SPI_SDA_Pin;
        GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
        GPIO_InitStruct.Pull = GPIO_NOPULL;
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
        HAL_GPIO_Init(SPI_SDA_GPIO_Port, &GPIO_InitStruct);
    }
    else if (state == 1)
    {
        GPIO_InitStruct.Pin = SPI_SDA_Pin;
        GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
        GPIO_InitStruct.Pull = GPIO_NOPULL;
        HAL_GPIO_Init(SPI_SDA_GPIO_Port, &GPIO_InitStruct);
    }
}

uint8_t rd_spi(uint8_t reg)
{
    sda_state(io_writ);
    uint8_t re_val = 0;
    uint8_t addr = reg;
    int i = 0;

    SPI_CSXLow();
    SPI_DCXLow();

    for (i = 0; i < 8; i++)
    {
        SPI_SCLLow();
        if (reg & 0x80)
        {
            SPI_SDAHigh();
        }
        else
        {
            SPI_SDALow();
        }
        reg = reg << 1;
        SPI_SCLHigh();
    }
    sda_state(io_read);
    for (i = 0; i < 8; i++)
    {
        SPI_SCLLow();
        re_val = re_val << 1;
        re_val = re_val + HAL_GPIO_ReadPin(SPI_SDA_GPIO_Port, SPI_SDA_Pin);
        SPI_SCLHigh();
    }
    SPI_CSXHigh();
    printf("reg %02x is %02X\n\r", addr, re_val);

    sda_state(io_writ);

    return re_val;
}

uint8_t rd_spi_04(void)
{
    sda_state(io_writ);
    uint8_t re_val1 = 0;
    uint8_t re_val2 = 0;
    uint8_t re_val3 = 0;
    uint8_t reg = 0x04;
    uint8_t state = 0;
    int i = 0;

    SPI_CSXLow();
    SPI_DCXLow();

    for (i = 0; i < 8; i++)
    {
        SPI_SCLLow();
        if (reg & 0x80)
        {
            SPI_SDAHigh();
        }
        else
        {
            SPI_SDALow();
        }
        reg = reg << 1;
        SPI_SCLHigh();
    }
    sda_state(io_read);

    SPI_SCLLow();
    SPI_SCLHigh();
    for (i = 0; i < 8; i++)
    {
        SPI_SCLLow();
        re_val1 = re_val1 << 1;
        re_val1 = re_val1 + HAL_GPIO_ReadPin(SPI_SDA_GPIO_Port, SPI_SDA_Pin);
        SPI_SCLHigh();
    }
    for (i = 0; i < 8; i++)
    {
        SPI_SCLLow();
        re_val2 = re_val2 << 1;
        re_val2 = re_val2 + HAL_GPIO_ReadPin(SPI_SDA_GPIO_Port, SPI_SDA_Pin);
        SPI_SCLHigh();
    }
    for (i = 0; i < 8; i++)
    {
        SPI_SCLLow();
        re_val3 = re_val3 << 1;
        re_val3 = re_val3 + HAL_GPIO_ReadPin(SPI_SDA_GPIO_Port, SPI_SDA_Pin);
        SPI_SCLHigh();
    }
    SPI_CSXHigh();
    printf("reg id is %02X %02X %02X\n\r", re_val1, re_val2, re_val3);

    sda_state(io_writ);

    return state;
}

void wr_cmd_parall1_8(uint16_t par)
{
    PAR_DCXLow();
    PAR_CSLow();
    GPIOB->ODR = par;

    PAR_WRLow();
    PAR_WRHigh();
    PAR_CSHigh();
}
void wr_dat_parall1_8(uint16_t par)
{
    PAR_DCXHigh();
    PAR_CSLow();
    GPIOB->ODR = par;

    PAR_WRLow();
    PAR_WRHigh();
    PAR_CSHigh();
}
void wr_cmd_parall1_16(uint16_t par)
{
    PAR_DCXLow();
    SPI_CSXLow();
    PAR_WRLow();
    GPIOB->ODR = par;

    PAR_WRHigh();
}
void wr_dat_parall1_16(uint16_t par)
{
    PAR_DCXHigh();
    PAR_CSLow();
    PAR_WRLow();
    GPIOB->ODR = par;

    PAR_WRHigh();
}

void wr_cmd_parall2_8(uint16_t par)
{
    PAR_DCXLow();
    SPI_CSXLow();
    PAR_WRLow();
    GPIOB->ODR = par << 1;

    PAR_WRHigh();
}
void wr_dat_parall2_8(uint16_t par)
{
    PAR_DCXHigh();
    PAR_WRLow();
    GPIOB->ODR = par << 1;

    PAR_WRHigh();
}
//**********************************read function begin********************************************
void pb_out(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    // db 0-7
    GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 |
                          GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
void pb_in(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    // db 0-7
    GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 |
                          GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
uint8_t i801_read_byte(void)
{
    uint8_t v;

    PAR_DCXHigh();
    PAR_RDLow();
    v = GPIOB->IDR;
    PAR_RDHigh();

    return v;
}
void rd_parall1_8(uint8_t c, uint8_t *d, uint32_t l)
{
    uint8_t buf[128];

    wr_cmd_parall1_8(c);
    pb_in();
    for (int i = 0; i < l; i++)
    {
        buf[i] = i801_read_byte();
    }
    PAR_CSHigh();
    pb_out();
    memcpy(d, buf, l);
}
//**********************************write display begin********************************************
void LCD_WriteCommand(uint16_t data)
{
    wr_cmd_parall1_8(data);
}

void LCD_WriteData(uint16_t data)
{
    wr_dat_parall1_8(data);
}

void Write(uint16_t DT, uint16_t par)
{
    if (DT == 0)
    {
        wr_cmd_4spi_8bcs(par);
    }
    else
    {
        wr_dat_4spi_8bcs(par);
    }
}

void WR_7789_REG(uint16_t data)
{
    wr_cmd_4spi_8bcs(data);
}

void WR_7789_PAR(uint16_t data)
{
    wr_dat_4spi_8bcs(data);
}

void Delay(uint32_t ms)
{
    HAL_Delay(ms);
}

void delay_ms(uint32_t ms)
{
    HAL_Delay(ms);
}

void init_ST7789V2(void)
{
    Write(Command, 0xF0);
    Write(Parameter, 0xC3);
    Write(Command, 0xF0);
    Write(Parameter, 0x96);
    Write(Command, 0xF0);
    Write(Parameter, 0xA5);
    Write(Command, 0xC1);
    Write(Parameter, 0x00);
    Write(Parameter, 0x09);
    Write(Parameter, 0xAD);
    Write(Parameter, 0x13);
    Write(Command, 0xC2);
    Write(Parameter, 0x00);
    Write(Parameter, 0x09);
    Write(Parameter, 0xAD);
    Write(Parameter, 0x13);
    Write(Command, 0xC3);
    Write(Parameter, 0x44);
    Write(Parameter, 0x03);
    Write(Parameter, 0x33);
    Write(Parameter, 0x04);
    Write(Command, 0xC4);
    Write(Parameter, 0x44);
    Write(Parameter, 0x03);
    Write(Parameter, 0x33);
    Write(Parameter, 0x04);
    Write(Command, 0xC5);
    Write(Parameter, 0x53);
    Write(Command, 0xD6);
    Write(Parameter, 0x00);
    Write(Command, 0xD7);
    Write(Parameter, 0x00);

    Write(Command, 0xE0);
    Write(Parameter, 0xF0);
    Write(Parameter, 0x3E);
    Write(Parameter, 0x05);
    Write(Parameter, 0x0B);
    Write(Parameter, 0x00);
    Write(Parameter, 0x78);
    Write(Parameter, 0x7F);
    Write(Parameter, 0x57);
    Write(Parameter, 0x7D);
    Write(Parameter, 0x70);
    Write(Parameter, 0x1F);
    Write(Parameter, 0x1F);
    Write(Parameter, 0x3F);
    Write(Parameter, 0x3F);

    Write(Command, 0xE1);
    Write(Parameter, 0xF0);
    Write(Parameter, 0x3B);
    Write(Parameter, 0x01);
    Write(Parameter, 0x03);
    Write(Parameter, 0x00);
    Write(Parameter, 0x76);
    Write(Parameter, 0x7F);
    Write(Parameter, 0x47);
    Write(Parameter, 0x7C);
    Write(Parameter, 0x70);
    Write(Parameter, 0x1F);
    Write(Parameter, 0x1A);
    Write(Parameter, 0x3F);
    Write(Parameter, 0x3F);

    Write(Command, 0xE5);
    Write(Parameter, 0xDD);
    Write(Parameter, 0xF5);
    Write(Parameter, 0xD2);
    Write(Parameter, 0x55);
    Write(Parameter, 0x22);
    Write(Parameter, 0x25);
    Write(Parameter, 0x10);
    Write(Parameter, 0x55);
    Write(Parameter, 0x55);
    Write(Parameter, 0x55);
    Write(Parameter, 0x55);
    Write(Parameter, 0x55);
    Write(Parameter, 0x55);
    Write(Parameter, 0x55);

    Write(Command, 0xE6);
    Write(Parameter, 0xDD);
    Write(Parameter, 0xF5);
    Write(Parameter, 0xD2);
    Write(Parameter, 0x55);
    Write(Parameter, 0x22);
    Write(Parameter, 0x25);
    Write(Parameter, 0x10);
    Write(Parameter, 0x55);
    Write(Parameter, 0x55);
    Write(Parameter, 0x55);
    Write(Parameter, 0x55);
    Write(Parameter, 0x55);
    Write(Parameter, 0x55);
    Write(Parameter, 0x55);
    Write(Command, 0xE7);
    Write(Parameter, 0x80);
    Write(Command, 0xEC);
    Write(Parameter, 0x00);
    Write(Parameter, 0x55);
    Write(Parameter, 0x00);
    Write(Parameter, 0x00);
    Write(Parameter, 0x00);
    Write(Parameter, 0x08);
    Write(Command, 0x36);
    Write(Parameter, 0x0C);
    Write(Command, 0x3A);
    Write(Parameter, 0x07);
    Write(Command, 0xB1);
    Write(Parameter, 0xFE);
    Write(Parameter, 0xDF);
    Write(Command, 0xB2);
    Write(Parameter, 0x09);
    Write(Command, 0xB3);
    Write(Parameter, 0x01);
    Write(Command, 0xB4);
    Write(Parameter, 0x01);
    Write(Command, 0xB5);
    Write(Parameter, 0x00);
    Write(Parameter, 0x08);
    Write(Parameter, 0x00);
    Write(Parameter, 0x08);
    Write(Command, 0xB6);
    Write(Parameter, 0xEF);
    Write(Parameter, 0x18);
    Write(Command, 0xA4);
    Write(Parameter, 0xC0);
    Write(Parameter, 0x63);
    Write(Command, 0xA5);
    Write(Parameter, 0x00);
    Write(Parameter, 0x00);
    Write(Parameter, 0x00);
    Write(Parameter, 0x00);
    Write(Parameter, 0x00);
    Write(Parameter, 0x0B);
    Write(Parameter, 0x2A);
    Write(Parameter, 0xBA);
    Write(Parameter, 0x02);
    Write(Command, 0xA6);
    Write(Parameter, 0x00);
    Write(Parameter, 0x00);
    Write(Parameter, 0x00);
    Write(Parameter, 0x00);
    Write(Parameter, 0x00);
    Write(Parameter, 0x0B);
    Write(Parameter, 0x2A);
    Write(Parameter, 0xBA);
    Write(Parameter, 0x02);
    Write(Command, 0xBA);
    Write(Parameter, 0x58);
    Write(Parameter, 0x0A);
    Write(Parameter, 0x34);
    Write(Parameter, 0x10);
    Write(Parameter, 0x22);
    Write(Parameter, 0x01);
    Write(Parameter, 0x00);
    Write(Command, 0xBB);
    Write(Parameter, 0x00);
    Write(Parameter, 0x1F);
    Write(Parameter, 0x00);
    Write(Parameter, 0x25);
    Write(Parameter, 0x83);
    Write(Parameter, 0x87);
    Write(Parameter, 0x18);
    Write(Parameter, 0x00);
    Write(Command, 0xBC);
    Write(Parameter, 0x00);
    Write(Parameter, 0x1F);
    Write(Parameter, 0x00);
    Write(Parameter, 0x25);
    Write(Parameter, 0x83);
    Write(Parameter, 0x87);
    Write(Parameter, 0x18);
    Write(Parameter, 0x00);
    Write(Command, 0xBD);
    Write(Parameter, 0x21);
    Write(Parameter, 0x12);
    Write(Parameter, 0xFF);
    Write(Parameter, 0xFF);
    Write(Parameter, 0x67);
    Write(Parameter, 0x58);
    Write(Parameter, 0x85);
    Write(Parameter, 0x76);
    Write(Parameter, 0xAB);
    Write(Parameter, 0xFF);
    Write(Parameter, 0x03);

    Write(Command, 0xED);
    Write(Parameter, 0xC3);
    Write(Command, 0xE4);
    Write(Parameter, 0x08);
    Write(Parameter, 0x2F);
    Write(Command, 0xA0);
    Write(Parameter, 0x00); // RGB setting DE+SYNC mode,
    Write(Parameter, 0x06);
    Write(Parameter, 0x06);

    Write(Command, 0x3A);
    Write(Parameter, 0x07);

    Write(Command, 0x36);
    Write(Parameter, 0x0C); // normal   0x36 0x18 MY

    Write(Command, 0x35);
    Write(Parameter, 0x00);

    Write(Command, 0x21);
    Write(Command, 0x11);
    Delay(120);
    Write(Command, 0x29);
}

/**
 * @brief Initialize and configure the SSD1963 LCD controller for 60Hz frame rate
 * @retval None
 */
void init_deepseek(LCD_Timing_t *timing)
{
    // 计算衍生参数
    uint16_t hdp = timing->width - 1;
    uint16_t vdp = timing->height - 1;

    // 串行RGB模式：水平总时间需要乘以3（每个像素3个时钟）
    uint16_t ht = (timing->width * 3) + timing->hbp + timing->hpw + timing->hfp;
    uint16_t vt = timing->height + timing->vbp + timing->vpw + timing->vfp;

    uint16_t hpw_reg = timing->hpw - 1;
    uint16_t vpw_reg = timing->vpw - 1;

    // 计算所需的像素时钟频率
    uint32_t required_pclk = LCD_CalculateSerialPixelClock(timing);

    // 计算像素时钟分频值 (串行RGB模式)
    uint32_t lcdc_fpr = LCD_CalculateLCDC_FPR(timing->pll_freq, required_pclk, 1);

    printf("LCD Timing Info:\n");
    printf("  Resolution: %dx%d\n", timing->width, timing->height);
    printf("  HT: %d, VT: %d\n", ht, vt);
    printf("  Required Pixel Clock: %ld Hz\n", required_pclk);
    printf("  LCDC_FPR: 0x%06lX\n", lcdc_fpr);

    // 1. 软件复位
    LCD_WriteCommand(0x01); // SOFT_RESET
    delay_ms(50);

    // 2. 设置PLL
    uint8_t m_value = 29; // 假设固定值，产生100MHz PLL
    uint8_t n_value = 2;

    LCD_WriteCommand(0xE2); // SET_PLL_MN
    LCD_WriteData(m_value);
    LCD_WriteData(n_value);
    LCD_WriteData(0x54); // 虚拟字节

    // 3. 启动PLL
    LCD_WriteCommand(0xE0); // SET_PLL
    LCD_WriteData(0x01);    // 使能PLL
    delay_ms(10);
    LCD_WriteCommand(0xE0); // SET_PLL
    LCD_WriteData(0x03);    // 使用PLL输出

    // 4. 设置像素数据接口
    LCD_WriteCommand(0xF0); // SET_PIXEL_DATA_INTERFACE
    LCD_WriteData(0x00);    // 8-bit MCU interface

    // 5. 设置LCD模式和分辨率
    LCD_WriteCommand(0xB0); // SET_LCD_MODE
    LCD_WriteData(0x20);    // 24-bit色深，使能FRC/抖动，LSHIFT下降沿锁存
    LCD_WriteData(0x80);    // B[6:5] = 10 (Serial RGB mode)
    // HDP (注意：这里仍然是实际的像素宽度，不是乘以3后的值)
    LCD_WriteData((hdp >> 8) & 0x07);
    LCD_WriteData(hdp & 0xFF);
    // VDP
    LCD_WriteData((vdp >> 8) & 0x07);
    LCD_WriteData(vdp & 0xFF);
    LCD_WriteData(0x00); // RGB顺序

    // 6. 设置水平时序 (注意：HT是乘以3后的值)
    LCD_WriteCommand(0xB4); // SET_HORI_PERIOD
    // HT (水平总时间 = 像素宽度×3 + HBP + HPW + HFP)
    LCD_WriteData((ht >> 8) & 0x07);
    LCD_WriteData(ht & 0xFF);
    // HPS (HBP)
    LCD_WriteData((timing->hbp >> 8) & 0x07);
    LCD_WriteData(timing->hbp & 0xFF);
    // HPW
    LCD_WriteData(hpw_reg & 0x7F);
    // LPS (水平显示起始位置)
    LCD_WriteData(0x00);
    LCD_WriteData(0x00);
    LCD_WriteData(0x00);

    // 7. 设置垂直时序
    LCD_WriteCommand(0xB6); // SET_VERT_PERIOD
    // VT
    LCD_WriteData((vt >> 8) & 0x07);
    LCD_WriteData(vt & 0xFF);
    // VPS (VBP)
    LCD_WriteData((timing->vbp >> 8) & 0x07);
    LCD_WriteData(timing->vbp & 0xFF);
    // VPW
    LCD_WriteData(vpw_reg & 0x7F);
    // FPS (垂直显示起始位置)
    LCD_WriteData(0x00);
    LCD_WriteData(0x00);

    // 8. 设置像素时钟频率
    LCD_WriteCommand(0xE6); // SET_LSHIFT_FREQ
    LCD_WriteData((lcdc_fpr >> 16) & 0x0F);
    LCD_WriteData((lcdc_fpr >> 8) & 0xFF);
    LCD_WriteData(lcdc_fpr & 0xFF);

    // 9. 退出睡眠模式
    LCD_WriteCommand(0x11); // EXIT_SLEEP_MODE
    delay_ms(5);

    // 10. 打开显示
    LCD_WriteCommand(0x29); // SET_DISPLAY_ON

    // 11. 设置显示区域
    LCD_WriteCommand(0x2A); // SET_COLUMN_ADDRESS
    LCD_WriteData(0x00);
    LCD_WriteData(0x00);
    LCD_WriteData((hdp >> 8) & 0x07);
    LCD_WriteData(hdp & 0xFF);

    LCD_WriteCommand(0x2B); // SET_PAGE_ADDRESS
    LCD_WriteData(0x00);
    LCD_WriteData(0x00);
    LCD_WriteData((vdp >> 8) & 0x07);
    LCD_WriteData(vdp & 0xFF);

    LCD_WriteCommand(0x2C); // WRITE_MEMORY_START
}

void LCD_RESET(void)
{
    LCD_RSTHigh();
    HAL_Delay(10); // ms
    LCD_RSTLow();
    HAL_Delay(10); // ms
    LCD_RSTHigh();
    HAL_Delay(10); // ms
}

void write_cmd(uint16_t par)
{
    wr_cmd_4spi_8bcs(par);
}

void write_data(uint16_t par)
{
    wr_dat_4spi_8bcs(par);
}

void fillcolor(uint8_t dat_r, uint8_t dat_g, uint8_t dat_b)
{
    uint32_t i, j;

    LCD_WriteCommand(0x2C); // Memory write

    for (i = 0; i < 240; i++)
        for (j = 0; j < 320; j++)
        {
            LCD_WriteData(dat_r);
            LCD_WriteData(dat_g);
            LCD_WriteData(dat_b);
        }
}

void keywait(uint32_t time)
{
    uint32_t i = 0;
    int pausing = 1;
    for (i = 0; i < time; i++)
    {
        if (HAL_GPIO_ReadPin(PAUSE_PA5_GPIO_Port, PAUSE_PA5_Pin) == GPIO_PIN_RESET)
        {
            HAL_Delay(20);
            if (HAL_GPIO_ReadPin(PAUSE_PA5_GPIO_Port, PAUSE_PA5_Pin) == GPIO_PIN_RESET)
            {
                while (HAL_GPIO_ReadPin(PAUSE_PA5_GPIO_Port, PAUSE_PA5_Pin) == GPIO_PIN_RESET)
                {
                    HAL_Delay(100);
                    printf("wait release\n\r");
                }
                printf("get key\n\r");
                while (pausing != 0)
                {
                    printf("pausing\n\r");
                    HAL_Delay(20);
                    if (HAL_GPIO_ReadPin(PAUSE_PA5_GPIO_Port, PAUSE_PA5_Pin) == GPIO_PIN_RESET)
                    {
                        printf("get 2nd key\n\r");
                        i = time - 2;
                        pausing = 0;
                        break;
                    }
                }
            }
        }
        HAL_Delay(1);
    }
}

void lcd_main(void)
{
    LCD_Timing_t timing;

    timing.width = 200;
    timing.height = 480;
    timing.hbp = 6;
    timing.hpw = 9;
    timing.hfp = 6;
    timing.vbp = 3;
    timing.vpw = 1;
    timing.vfp = 3;
    timing.frame_rate = 60;      // 60Hz刷新率
    timing.pll_freq = 100000000; // 100MHz

    LCD_RESET();
    rd_spi(0xDA);
    rd_spi(0xDB);
    rd_spi(0xDC);
    init_ST7789V2();
    // init_SSD1963();
    init_deepseek(&timing);

    sdcard_init();
    bmpDrawFile("6.bmp");
    keywait(Interval);
    bmpDrawFile("7.bmp");
    keywait(Interval);
    bmpDrawFile("8.bmp");
    keywait(Interval);
    bmpDrawFile("9.bmp");
    keywait(Interval);
    bmpDrawFile("10.bmp");
    keywait(Interval);

    Write(Command, 0x28);
    HAL_Delay(50);
    Write(Command, 0x10);
    while (1)
    {
        HAL_Delay(100);
    }
}